package devastator;
import robocode.*;
import robocode.HitRobotEvent;
import robocode.Robot;
import robocode.ScannedRobotEvent;
import java.awt.*;
import java.util.Random;
import java.lang.Math;

import robocode.RobocodeFileOutputStream;
import static robocode.util.Utils.normalRelativeAngleDegrees;
import java.io.IOException;


/**
 * Devastator - a robot by Soldatov Dmitry
 */
public class Devastator extends AdvancedRobot
{
	private Random rg = new Random(); //for colours changing
	private int change = 1; // parametr for direction changing

	/**
	 * run: Devastator's default behavior
	 */
	
	public void run() {
		setBulletColor(Color.white);

		setAdjustGunForRobotTurn(true);

		while(true) {
			changeCamouflage();
			turnRadarRight(360); //always scan battlefield
		}
	}

	public double normalize(double in){
		return Math.abs(in) >= 180 ? in - Math.signum(in)*360 : in;
	}
	
	public void onScannedRobot(ScannedRobotEvent e) {

		double D = e.getDistance();

		double gunHeading = normalize(getGunHeading()); //gun normilized (-180..180) direction (������������ ���������)
	
		int bulletPower = D >= 400 ? 1 : 2;
		double bulletVelocity = (20-3*bulletPower);
		
		double enemyBearing = e.getBearing(); //���� ��������� ����� � �������� (-180..180), ������������ ����������� �������
		double enemyPath = D/bulletVelocity*e.getVelocity();
		double Iangle = normalize(normalize(getHeading()) + enemyBearing); ////���� ��������� ����� � �������� (-180..180), ������������ ���������
		Iangle = Iangle < 0 ? Iangle + 360 : Iangle; //(0 .. 360)
		double IIangle = e.getHeading(); //(0..360)

		//new enemy coordinates
		double yes = Math.cos(IIangle*Math.PI/180)*enemyPath+Math.cos(Iangle*Math.PI/180)*D+getY();
		double xes = Math.sin(IIangle*Math.PI/180)*enemyPath+Math.sin(Iangle*Math.PI/180)*D+getX();
		
		//double newDistance = Math.sqrt(Math.pow(getX()-xes,2) + Math.pow(getY()-yes,2));

		double tg = (xes-getX())/(yes-getY());
		double xangle = normalize(Math.signum(yes-getY()) < 0 ? 180 - Math.signum(yes-getY())*Math.atan(tg)*180/Math.PI : Math.atan(tg)*180/Math.PI);
		
		turnGunLeft(normalize(gunHeading-xangle));
		
		//fire distance dependence
		if (D>=600) {
			//too far, don't fire
		} else if (D>=400) {	
			fire(bulletPower);
		} else if (D>=5){
			fire(bulletPower);
		} else {
			fire(3);
		}
		
		//movement strategy
		if (D >= 200){ //if too far, get closer to the enemy
			setAhead(500);
			setTurnLeft(-enemyBearing);
			waitFor(new TurnCompleteCondition(this));
		} else if(D <= 40){ //if too close, move back from the enemy
			setBack(500);
			setTurnLeft(-enemyBearing);
			waitFor(new TurnCompleteCondition(this));
		} else { //spin around enemy
			setTurnLeft(90-enemyBearing);
			setAhead(change*100);
		}
	}

	/**
	 * onHitByBullet, onHitWall: change movement direction
	 */
	public void onHitByBullet(HitByBulletEvent e) {
		change *= -1;
	}
	
	public void onHitWall(HitWallEvent e) {
		change *= -1;
	}

	//set random colours. It's a joke method.
	private void changeCamouflage(){

			setBodyColor(new Color(rg.nextInt(256),rg.nextInt(256),rg.nextInt(256)));
			setGunColor(new Color(rg.nextInt(256),rg.nextInt(256),rg.nextInt(256)));
			setRadarColor(new Color(rg.nextInt(256),rg.nextInt(256),rg.nextInt(256)));
			setScanColor(new Color(rg.nextInt(256),rg.nextInt(256),rg.nextInt(256)));
	}

}																
					